package implementation;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import entility.Job;
import entility.JobImpl;
import entility.Machine;
import entility.Notification;

public class LerArquivo {

	String path;
	long tamanhoParte;
	List<Machine> hosts;
	static List<Integer> numbers;
	Integer totalCores;
	long tamFile;
	List<CoreStatus> statusCore;
	

	public long getTamanhoParte() {
		return tamanhoParte;
	}

	public void setTamanhoParte() {
		this.tamanhoParte = (tamFile / 4) / totalCores;
	}

	public Integer getTotalCores() {
		return totalCores;
	}

	public void setTotalCores() {
		this.totalCores = totalCoresCluster();
	}

	public LerArquivo(String path) {
		super();
		this.path = path;
		
		this.statusCore = new ArrayList<CoreStatus>();
		this.numbers = new ArrayList<Integer>();
		File file = new File(path);
		
		this.tamFile = file.length();
		
	}
	
	public void inicializaStatusCores(){
		
		Integer aux = new Integer(0);
		CoreStatus e;
		for(Machine machine: hosts){
			aux = machine.getCores();
			for(int i = 1; i<=aux.intValue();i++){
				//System.out.println(machine.ip);
				e = new CoreStatus(machine.ip,i,false);
				statusCore.add(e);
			}
		}
	}
	
	public void initHosts(Machine mainServer) throws Exception {
		Job job = new JobImpl(Notification.CLIENT);
		job.setMethod("getHosts");
		Job response = mainServer.getMessage(job);
		this.hosts = response.getMachineList();
		
		
	}
	public Integer totalCoresCluster(){
		
		Integer numCores = new Integer(0);
		for(Machine machine: hosts){
			
			numCores = numCores + machine.getCores();
		}
		
		return numCores;
	}
	
	
	public void lerArquivo() {
		File file = new File(path);
		DataInputStream in;
		byte[] byteToInt = new byte[4];
		long quantBytes = 0;
		int newNumber;
		
		try {
			in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
			//System.out.println(tamanhoParte);
			//System.out.println(totalCores);
			while (in.available() != 0) {
				byteToInt[(int) (quantBytes % 4)] = in.readByte();
				quantBytes++;
				if ((quantBytes % 4) == 0) {
					newNumber = byteArrayToInt(byteToInt);
					//System.out.println(newNumber);
					numbers.add(newNumber);
					envia();
					
				}
				/*if((quantBytes % 1000) == 0){
					System.out.println(quantBytes);
				}*/
			}
			
			in.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	private void envia() {
		// TODO Auto-generated method stub
		if(tamanhoParte == numbers.size()){
			for(CoreStatus s: statusCore){
				if(!s.isEnviou()){
					//System.out.println(s.getIP());
					DistribuiArquivo d = new DistribuiArquivo(new ArrayList<Integer>(numbers),s.getIP());
					d.run();
					s.enviou = true;
					//System.out.println("BYTES " + numbers.size());
					numbers.clear();
					break;
				}
			}
		}
		
		
	}

	public int byteArrayToInt(byte[] b) {
		int value = 0;
		for (int i = 0; i < 4; i++) {
			int shift = (4 - 1 - i) * 8;
			value += (b[i] & 0x000000FF) << shift;
		}
		return value;
	}

	
}
